package com.koko.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

@Slf4j
public class IOUtil {
    /**
     * 读取文件中的所有文本内容并返回一个字符串。
     *
     * @param filePath 文件的路径
     * @return 文件中的文本内容
     * @throws IOException 如果读取过程中出现错误
     */
    public static String readFileToString(String filePath) throws IOException {
        StringBuilder contentBuilder = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                contentBuilder.append(line).append("\n"); // 添加换行符，保持原始文件格式
            }
        } catch (FileNotFoundException e) {
            throw new FileNotFoundException("未能找到文件：" + filePath);
        }
        return contentBuilder.toString();
    }

    /**
     * 将给定的字符串写入到指定的txt文件中。
     *
     * @param content 要写入的字符串内容
     * @param txtPath 目标文件的路径，包括文件名
     * @throws IOException 如果文件写入过程中出现错误
     */
    public static void writeStringToTxt(String content, String txtPath) {
        // 使用try-with-resources语句确保FileWriter正确关闭，防止资源泄漏
        try (FileWriter writer = new FileWriter(txtPath, false)) {  // 第二个参数为false表示不追加，直接覆盖
            writer.write(content);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 保存文件到指定路径，如果存在同名文件则覆盖。
     *
     * @param file           MultipartFile 文件对象
     * @param targetLocation 存储目标路径
     * @throws IOException 如果文件保存过程中出现错误
     */
    public static String saveFile(MultipartFile file, String targetLocation, String... fileName) {
        //原始文件名
        String suffix = getFileSuffix(file);
        // 确定文件名
        String finalFileName = fileName.length > 0 ? fileName[0] : UUID.randomUUID().toString() + suffix;

        createDirectory(targetLocation);

        try {
            //将文件转存到指定位置
            File f = new File(targetLocation + finalFileName);
            file.transferTo(f);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return finalFileName;
    }

    /**
     * 删除指定的文件或目录（包括子目录和文件）
     *
     * @param path 要删除的文件或目录路径
     * @return 删除成功返回true，否则返回false
     */
    public static boolean deleteFileOrDirectory(String path) {
        File file = new File(path);
        if (file.isDirectory()) {
            // 获取目录下所有文件和目录
            File[] files = file.listFiles();
            if (files != null) {
                for (File f : files) {
                    deleteFileOrDirectory(f.getPath());  // 递归删除每一个子文件或子目录
                }
            }
        }
        // 删除文件或空目录
        return file.delete();
    }

    /**
     * 创建一个文本文件，如果文件名未指定，则默认使用 "introduction.txt"。
     *
     * @param txtName 文件名，可选，如果未提供，则使用默认名称 "introduction.txt"
     */
    public static String createTxtFile(String targetLocation, String... txtName) {
        // 确定文件名
        String fileName = txtName.length > 0 ? txtName[0] : UUID.randomUUID().toString() + ".txt";

        Path path = Paths.get(targetLocation + fileName);

        try {
            // 检查文件是否已存在
            if (!Files.exists(path)) {
                // 创建新文件
                Files.createFile(path);
                log.error("文件已创建:" + path.toAbsolutePath());
            } else {
                log.error("文件已存在: " + path.toAbsolutePath());
            }
        } catch (IOException e) {
            log.error("创建文件时出错: " + e.getMessage());
        }
        return fileName;
    }

    public static String saveStringToTxt(String content, String targetLocation, String... txtName) {
        // 确定文件名
        String fileName = txtName.length > 0 ? txtName[0] : UUID.randomUUID().toString() + ".txt";

        Path path = Paths.get(targetLocation + fileName);

        try {
            // 检查文件是否已存在
            if (!Files.exists(path)) {
                // 创建新文件
                Files.createFile(path);
                log.error("文件已创建:" + path.toAbsolutePath());
            } else {
                log.error("文件已存在: " + path.toAbsolutePath());
            }
        } catch (IOException e) {
            log.error("创建文件时出错: " + e.getMessage());
        }

        writeStringToTxt(content, targetLocation + fileName);

        return fileName;
    }

    public static void createDirectory(String path) {
        //创建一个目录对象
        File dir = new File(path);
        //判断当前目录是否存在
        if (!dir.exists()) {
            //目录不存在，需要创建
            dir.mkdirs();
        }
    }

    /**
     * 获取文件后缀名
     * @param file
     * @return
     */
    public static String getFileSuffix(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        return originalFilename.substring(originalFilename.lastIndexOf("."));
    }

    /**
     * 读取文件并去除转义字符，返回处理后的 HTML 字符串。
     *
     * @param filePath 文件的路径。
     * @return 处理后的文件内容作为字符串。
     */
    public static String readHtmlContentFromTxt(String filePath) {
        BufferedReader reader = null;
        StringBuilder contentBuilder = new StringBuilder();

        try {
            reader = new BufferedReader(new FileReader(filePath));
            String line;

            while ((line = reader.readLine()) != null) {
                // 替换文件中的转义字符
                String processedLine = line.replace("\t", "") // 去掉制表符
                        .replace("\n", "") // 去掉换行符
                        .replace("\r", ""); // 去掉回车符
                contentBuilder.append(processedLine);
            }

            return contentBuilder.toString();
        } catch (IOException e) {
            e.printStackTrace();
            return null; // 如果发生错误，返回 null
        } finally {
            if (reader != null) {
                try {
                    reader.close(); // 确保文件流关闭
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 将 HTML 字符串写入到 TXT 文件中，确保不包含转义字符。
     *
     * @param htmlContent HTML 内容作为字符串。
     * @param filePath 目标文件的路径。
     * @return 返回是否写入成功。
     */
    public static boolean writeHtmlContentToTxt(String htmlContent, String filePath) {
        BufferedWriter writer = null;

        try {
            writer = new BufferedWriter(new FileWriter(filePath));
            // 在写入前替换转义字符
            String processedContent = htmlContent.replace("\t", "")
                    .replace("\n", "")
                    .replace("\r", "");
            writer.write(processedContent);
            return true; // 成功写入
        } catch (IOException e) {
            e.printStackTrace();
            return false; // 写入失败
        } finally {
            if (writer != null) {
                try {
                    writer.close(); // 确保文件流关闭
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 分块存储
     * @param chunk
     * @param targetLocation
     * @param index
     * @param fileName
     * @return
     */
    public static void saveTempChunkFile(MultipartFile chunk, String targetLocation, Integer index, String fileName) {

        createDirectory(targetLocation);

        File chunkFile = new File(targetLocation + "/" + fileName + "." + index);

        try (OutputStream os = new FileOutputStream(chunkFile)) {
            os.write(chunk.getBytes());
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 合并视频文件
     * @param dir
     * @param fileName
     * @param totalChunks
     */
    public static void mergeFile(String dir, String fileName, int totalChunks) {
        File mergedFile = new File(dir + "/" + fileName);
        try (OutputStream os = new FileOutputStream(mergedFile)) {
            for (int i = 0; i < totalChunks; i++) {
                File chunkFile = new File(dir + "/" + fileName + "." + i);
                Files.copy(Paths.get(chunkFile.getAbsolutePath()), os);
                chunkFile.delete(); // 删除临时分块文件
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }



}
